package com.example.demo.core.web.core.model;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.annotation.JSONField;
import com.example.demo.core.web.core.enums.GlobalErrorCodeConstants;
import com.example.demo.core.web.core.exception.ServerException;
import com.example.demo.core.web.core.exception.ServiceException;
import java.io.Serializable;
import java.util.Objects;
import lombok.Data;

/**
 * 通用返回
 *
 * @author airhead
 * @param <T> 数据泛型
 */
@Data
public class CommonResult<T> implements Serializable {

  /**
   * 错误码
   *
   * @see ErrorCode#getCode()
   */
  private Integer code;

  /** 返回数据 */
  private T data;

  /**
   * 错误提示，用户可阅读
   *
   * @see ErrorCode#getMsg() ()
   */
  private String msg;

  /**
   * 将传入的 result 对象，转换成另外一个泛型结果的对象
   *
   * <p>因为 A 方法返回的 CommonResult 对象，不满足调用其的 B 方法的返回，所以需要进行转换。
   *
   * @param result 传入的 result 对象
   * @param <T> 返回的泛型
   * @return 新的 CommonResult 对象
   */
  public static <T> CommonResult<T> error(CommonResult<?> result) {
    return error(result.getCode(), result.getMsg());
  }

  public static <T> CommonResult<T> error(Integer code, String message) {
    CommonResult<T> result = new CommonResult<>();
    result.code = code;
    result.msg = message;
    return result;
  }

  public static <T> CommonResult<T> error(ErrorCode errorCode) {
    return error(errorCode.getCode(), errorCode.getMsg());
  }

  public static <T> CommonResult<T> success(T data) {
    CommonResult<T> result = new CommonResult<>();
    result.code = GlobalErrorCodeConstants.SUCCESS.getCode();
    result.data = data;
    result.msg = "";
    return result;
  }

  public static boolean isSuccess(Integer code) {
    return Objects.equals(code, GlobalErrorCodeConstants.SUCCESS.getCode());
  }

  public static <T> CommonResult<T> error(ServiceException serviceException) {
    return error(serviceException.getCode(), serviceException.getMessage());
  }

  /**
   * 避免 jackson 序列化
   *
   * @return
   */
  @JSONField(serialize = false)
  public boolean isSuccess() {
    return isSuccess(code);
  }

  // ========= 和 Exception 异常体系集成 =========

  /**
   * 避免 jackson 序列化
   *
   * @return
   */
  @JSONField(serialize = false)
  public boolean isError() {
    return !isSuccess();
  }

  /** 判断是否有异常。如果有，则抛出 {@link ServiceException} 异常 */
  public void checkError() throws ServiceException {
    if (isSuccess()) {
      return;
    }
    // 服务端异常
    if (GlobalErrorCodeConstants.isServerErrorCode(code)) {
      throw new ServerException(code, msg);
    }
    // 业务异常
    throw new ServiceException(code, msg);
  }

  /** 判断是否有异常。如果有，则抛出 {@link ServiceException} 异常 如果没有，则返回 {@link #data} 数据 避免 jackson 序列化 */
  @JSONField(serialize = false)
  public T getCheckedData() {
    checkError();
    return data;
  }

  public String toJson() {
    return JSON.toJSONString(this);
  }
}
